home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************
- VGLGIF.C
-
- vglGif( char* file, char far* buffer, char far* palette,
- int* width, int* height );
-
- Routine to load a 256 color .GIF file into a memory buffer. *Only* 256
- color images are supported here! Sorry, no routines to SAVE .GIFs...
- Memory required is allocated on the fly and no checks are in place. If you
- don't have enough memory it will likely crash. It's easy to add the checks
- yourself, just put one after each call to malloc(). If you supply a pointer
- to a palette, it will be filled in. If you supply a pointer to a width
- and/or height variable, it will be filled in as well.
-
- Mark Morley
- morley@camosun.bc.ca
- *****************************************************************************/
-
- #include <stdio.h>
-
- #define MAX_CODES 4096
-
- static FILE* fp;
- static int curr_size;
- static int clear;
- static int ending;
- static int newcodes;
- static int top_slot;
- static int slot;
- static int navail_bytes = 0;
- static int nbits_left = 0;
- static unsigned char b1;
- static unsigned char byte_buff[257];
- static unsigned char* pbytes;
- static unsigned char* stack;
- static unsigned char* suffix;
- static unsigned int* prefix;
-
- static unsigned long code_mask[13] =
- {
- 0L,
- 0x0001L, 0x0003L,
- 0x0007L, 0x000FL,
- 0x001FL, 0x003FL,
- 0x007FL, 0x00FFL,
- 0x01FFL, 0x03FFL,
- 0x07FFL, 0x0FFFL
- };
-
- static int pascal
- get_next_code()
- {
- register int i;
- static unsigned long ret;
-
- if( ! nbits_left )
- {
- if( navail_bytes <= 0 )
- {
- pbytes = byte_buff;
- navail_bytes = getc( fp );
- if( navail_bytes )
- for( i = 0; i < navail_bytes; ++i )
- *(byte_buff + i) = getc( fp );
- }
- b1 = *pbytes++;
- nbits_left = 8;
- --navail_bytes;
- }
- ret = b1 >> (8 - nbits_left);
- while( curr_size > nbits_left )
- {
- if( navail_bytes <= 0 )
- {
- pbytes = byte_buff;
- navail_bytes = getc( fp );
- if( navail_bytes )
- for( i = 0; i < navail_bytes; ++i )
- *(byte_buff + i) = getc( fp );
- }
- b1 = *pbytes++;
- ret |= b1 << nbits_left;
- nbits_left += 8;
- --navail_bytes;
- }
- nbits_left -= curr_size;
-
- return( (int) (ret & *(code_mask + curr_size)) );
- }
-
- vglGif( char* file, char far* buffer, char far* pal, int* width, int* height )
- {
- unsigned char* sp;
- int code, fc, oc;
- int i;
- unsigned char size;
- int c;
- unsigned char buf[1028];
- unsigned char red;
- unsigned char grn;
- unsigned char blu;
-
- fp = fopen( file, "rb" );
- if( !fp )
- return( 0 );
- fread( buf, 1, 6, fp );
- if( strncmp( buf, "GIF", 3 ) )
- {
- fclose( fp );
- return( 0 );
- }
- fread( buf, 1, 7, fp );
- for( i = 0; i < 768; )
- {
- red = getc( fp );
- grn = getc( fp );
- blu = getc( fp );
-
- if( pal )
- {
- pal[i++] = red >> 2;
- pal[i++] = grn >> 2;
- pal[i++] = blu >> 2;
- }
- else
- i += 3;
- }
- fread( buf, 1, 5, fp );
- i = getw( fp );
- if( width )
- *width = i;
- i = getw( fp );
- if( height )
- *height = i;
- if( !buffer )
- return( 1 );
- fread( buf, 1, 1, fp );
- size = getc( fp );
- if( size < 2 || 9 < size )
- {
- fclose( fp );
- return( 0 );
- }
-
- stack = (unsigned char*) malloc( MAX_CODES + 1 );
- suffix = (unsigned char*) malloc( MAX_CODES + 1 );
- prefix = (unsigned int*) malloc( sizeof(int) * (MAX_CODES + 1) );
-
- curr_size = size + 1;
- top_slot = 1 << curr_size;
- clear = 1 << size;
- ending = clear + 1;
- slot = newcodes = ending + 1;
- navail_bytes = nbits_left = 0;
- oc = fc = 0;
- sp = stack;
- while( (c = get_next_code()) != ending )
- {
- if( c == clear )
- {
- curr_size = size + 1;
- slot = newcodes;
- top_slot = 1 << curr_size;
- while( (c = get_next_code()) == clear );
- if( c == ending )
- break;
- if( c >= slot )
- c = 0;
- oc = fc = c;
- *buffer++ = c;
- }
- else
- {
- code = c;
- if( code >= slot )
- {
- code = oc;
- *sp++ = fc;
- }
- while( code >= newcodes )
- {
- *sp++ = *(suffix + code);
- code = *(prefix + code);
- }
- *sp++ = code;
- if( slot < top_slot )
- {
- *(suffix + slot) = fc = code;
- *(prefix + slot++) = oc;
- oc = c;
- }
- if( slot >= top_slot && curr_size < 12 )
- {
- top_slot <<= 1;
- ++curr_size;
- }
- while( sp > stack )
- {
- --sp;
- *buffer++ = *sp;
- }
- }
- }
- free( stack );
- free( suffix );
- free( prefix );
- fclose( fp );
- return( 1 );
- }
-